/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2015年7月6日
 * V4.0
 */
package com.jphenix.driver.ftp;

import com.jphenix.kernel.baseobject.instanceb.ABase;
import com.jphenix.kernel.objectloader.interfaceclass.IBeanRegister;
import com.jphenix.kernel.objectloader.interfaceclass.IBeanRegisterChild;
import com.jphenix.sdk.ftp.FtpDirParser;
import com.jphenix.share.util.BaseUtil;
import com.jphenix.standard.docs.BeanInfo;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.docs.Running;
import com.jphenix.standard.exceptions.MsgException;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

/**
 * FTP连接管理类
 * @author 马宝刚
 * 2015年7月6日
 */
@ClassInfo({"2015-07-06 17:20","FTP连接管理类"})
@BeanInfo({"ftpmanager"})
@Running({"1","start"})
public class FTPManager extends ABase implements IBeanRegister {

    protected TaskThread tt = null; //任务线程
    //服务器连接信息容器
    protected Map<String,Map<String,String>> infoMap = new HashMap<String,Map<String,String>>();
    //ftp客户端容器
    protected Map<String,FtpClient> clientMap = new Hashtable<String,FtpClient>();
    
    protected long intervalTime = 60000; //间隔时间 默认60秒
    
    
    /**
     * 任务线程
     * @author 马宝刚
     * 2015年7月6日
     */
    protected class TaskThread extends Thread {
        
        /**
         * 构造函数
         * @author 马宝刚
         */
        public TaskThread() {
            super("FTPManager-TaskThread");
        }
        
        /**
         * 覆盖函数
         */
        @Override
        public void run() {
            if(intervalTime<1) {
                intervalTime = 600000;
            }
            List<String> keys = null; //ftp连接源主键序列
            FtpClient fcEle; //ftp客户端元素
            while(true) {
                keys = BaseUtil.getMapKeyList(clientMap);
                for(String key:keys) {
                    fcEle = clientMap.get(key);
                    if(fcEle==null || fcEle.lastTime+intervalTime<System.currentTimeMillis()) {
                        clientMap.remove(key);
                    }
                }
                try {
                    Thread.sleep(intervalTime);
                }catch(Exception e) {
                    break;
                }
            }
        }
    }
    
    
    /**
     * 构造函数
     * @author 马宝刚
     */
    public FTPManager() {
        super();
    }

    /**
     * 启动服务
     * 2015年7月6日
     * @author 马宝刚
     */
    public void start() {
        tt = new TaskThread();
        tt.start();
    }
    
    /**
     * 通过连接源主键获取ftp客户端
     * @param sourceKey 连接源主键
     * @return ftp客户端类实例
     * @throws Exception 异常
     * 2015年7月6日
     * @author 马宝刚
     */
    public FtpClient getFtp(String sourceKey) throws Exception {
        //先获取
        FtpClient fc = clientMap.get(sourceKey);
        if(fc==null) {
            //获取对应的连接信息
            Map<String,String> info = infoMap.get(sourceKey);
            if(info==null) {
                //获取参数值
            	String value = prop.getParameter("ftp/"+sourceKey+"/ip");
            	if(value.length()<1) {
            		throw new MsgException(this,"Ftp Info not found SourceKey:["+sourceKey+"]");
            	}
            	info = new HashMap<String,String>();
            	infoMap.put(sourceKey,info);
            	
            	info.put("ip",value); //ip地址
            	info.put("port",prop.getParameter("ftp/"+sourceKey+"/port"));
            	info.put("pasv",prop.getParameter("ftp/"+sourceKey+"/pasv"));
            	info.put("user",prop.getParameter("ftp/"+sourceKey+"/user"));
            	info.put("pwd",prop.getParameter("ftp/"+sourceKey+"/pwd"));
            	info.put("path",prop.getParameter("ftp/"+sourceKey+"/path"));
            	info.put("dir_parser",prop.getParameter("ftp/"+sourceKey+"/dir_parser"));
            }
            fc = new FtpClient();
            fc.setBase(this);
            fc.ip = str(info.get("ip"));
            fc.port = sint(info.get("port"));
            fc.pasv = boo(info.get("pasv"));
            fc.user = str(info.get("user"));
            fc.pwd = str(info.get("pwd"));
            fc.path = str(info.get("path"));
            
            //目录列表解析器
            String dirParser = str(info.get("dir_parser"));
            if(dirParser.length()>0) {
            	try {
            		//构建目录列表解析类
            		@SuppressWarnings("unchecked")
					Class<FtpDirParser> dirParserCls = 
            				(Class<FtpDirParser>)Class.forName(dirParser);
            		fc.dirParser = dirParserCls.newInstance();
            	}catch(Exception e) {
            		e.printStackTrace();
            	}
            }
            fc.connect(false); //建立连接
            
            clientMap.put(sourceKey,fc);
        }else {
            fc.connect(false);
        }
        return fc;
    }
    

    /**
     * 覆盖方法
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public boolean regist(Object bean) {
        if(!(bean instanceof Map)) {
            return false;
        }
        //获取连接源主键
        String id = str(((Map)bean).get("id"));
        if(id.length()<1) {
            return false;
        }
        infoMap.put(id,(Map)bean);
        if(bean instanceof IBeanRegisterChild) {
            ((IBeanRegisterChild)bean).setRegister(this);
            ((IBeanRegisterChild)bean).afterRegister();
        }
        return true;
    }

    /**
     * 覆盖方法
     */
    @Override
    public void unRegist(Object bean) {
        if(bean==null) {
            return;
        }
        if(bean instanceof IBeanRegisterChild) {
            ((IBeanRegisterChild)bean).beforeUnRegister();
        }
    }
}